package com.hd.trans.ui.model

import com.hd.trans.R
import com.hd.trans.common.Constants
import com.hd.trans.db.DataBaseMgr
import com.hd.trans.db.bean.HuDunLanguage
import com.hd.trans.db.bean.TranslateRecord
import com.hd.trans.extension.ioExecute
import com.hd.trans.homefun.RecordType
import com.hd.trans.network.bean.HdLangWrapper
import com.hd.trans.network.bean.TranslateTextBean
import com.hd.trans.network.component.HdTranslateComponent
import com.hd.trans.network.component.LangDetectComponent.firstLangDetect
import com.hd.trans.network.component.TranslateCallback
import com.hd.trans.network.repository.RomaRepository
import com.hd.trans.utils.ToastUtils
import com.hd.trans.utils.preference.Preferences.isOffline
import com.hd.trans.utils.preference.Preferences.isPinyinEnable
import kotlinx.coroutines.Job
import java.util.concurrent.CountDownLatch

class TextTransViewModel: BaseViewModel() {
    private var mPinyinCallBack: ((TranslateTextBean?) -> Unit)? = null
    private var mPinyinJob: Job? = null

    fun languageDetect(text: String?) {
        firstLangDetect(text!!) { result: String? ->
            var result = result ?: return@firstLangDetect null
            if (result == "br") {
                result = "en"
            }
            val language = DataBaseMgr.getInstance().getLanguageByTransCode(result)
            if (language != null) {
                detectLang.value = language
            }
            null
        }
    }

    fun getRecordById(recordId: Long) {
        val record = DataBaseMgr.getInstance().getRecordById(recordId)
        operateRecord.value = record
    }

    /**
     * 收藏
     */
    fun collectRecord() {
        val record: TranslateRecord = operateRecord.value ?: return
        record.isCollected = !record.isCollected
        DataBaseMgr.getInstance().updateTranslateRecord(record)
        operateRecord.value = record
        if(record.isCollected){
            ToastUtils.showNormal(R.string.collection_success)
        }else{
            ToastUtils.showNormal(R.string.collection_cancel)
        }
    }

    /**
     * 翻译
     */
    fun translationText(
        translateComponent: HdTranslateComponent,
        origContent: String,
        callBack: (() -> Unit)? = null
    ) {
        if (languageFrom.value == null || languageTo.value == null) {
            return
        }
        isLoading.value = true
        translateComponent.translationText(
            origContent,
            languageFrom.value!!.translateCode,
            languageTo.value!!.translateCode,
            isOffline,
            object : TranslateCallback {
                override fun onTranslateFailed(code: Int, msg: String) {
                    isLoading.value = false
                    if (code == Constants.ResponseCode.ERROR_IS_DANGER
                        || code == Constants.ResponseCode.ERROR_COMM
                        || code == Constants.ResponseCode.ERROR_NETWORK
                    ) {
                        ToastUtils.showError(msg)
                    } else {
                        ToastUtils.showError(R.string.fanyi_faith_tip)
                    }
                }

                override fun onTranslateCompleted(
                    data: String?,
                    fromLangCode: String,
                    toLangCode: String,
                    status: Boolean
                ) {

                    var result = data?.trim() ?: ""
                    if (result.isEmpty()){
                        ToastUtils.showNormal( R.string.fanyi_faith_tip)
                        return
                    }
                    if (result.endsWith("\n")) {
                        val endIndex = result.lastIndexOf("\n")
                        result = result.substring(0, endIndex)
                    }

                    //创建翻译记录
                    val record = TranslateRecord()
                    record.isVoice = false
                    record.isNation = false
                    record.isCollected = false
                    record.recordType = RecordType.TEXT
                    record.languageFrom = languageFrom.value
                    record.languageTo = languageTo.value
                    record.contentOrig = origContent
                    record.contentTranslate = result
                    record.triggerTime = System.currentTimeMillis()

                    val instance = DataBaseMgr.getInstance()
                    if (isOffline || !isPinyinEnable) {
                        isLoading.value = false
                        instance.addTranslateRecord(record)
                        operateRecord.value = record
                        //刷新历史记录
                        refreshRecords(false)
                        callBack?.invoke()
                    } else {
                        //标音
                        getResultPinyin(
                            origContent,
                            languageFrom.value!!,
                            result,
                            languageTo.value!!
                        ){
                            isLoading.value = false
                            record.pinyinOrig = it?.origPinyin
                            record.pinyinTranslate = it?.tranPinyin

                            instance.addTranslateRecord(record)
                            operateRecord.value = record
                            //刷新历史记录
                            refreshRecords(false)
                            callBack?.invoke()
                        }
                    }
                }
            }
        )
    }

    private fun getResultPinyin(
        fromText: String,
        fromLang: HuDunLanguage,
        toText: String,
        toLang: HuDunLanguage,
        block: (TranslateTextBean?) -> Unit
    ) {
        mPinyinCallBack = block
        mPinyinJob?.cancel()
        mPinyinJob = launch {
            call(false) {
                ioExecute {
                    val countDownLatch = CountDownLatch(2)
                    var fromPinyin:String? = null
                    var toPinyin:String? = null

                    pinyin(fromText,fromLang){
                        fromPinyin = it
                        countDownLatch.countDown()
                    }

                    pinyin(toText,toLang){
                        toPinyin = it
                        countDownLatch.countDown()
                    }

                    countDownLatch.await()

                    TranslateTextBean(fromText,toText,fromPinyin,toPinyin)
                }.apply {
                    if (block == mPinyinCallBack) {
                        block.invoke(this)
                    }
                }
            }.catch {
                if (block == mPinyinCallBack) {
                    block.invoke(null)
                }
            }
        }
    }

    private suspend fun pinyin(text: String, lang:HuDunLanguage, block: (String?) -> Unit) {
        when(lang.translateCode){
            HdLangWrapper.KO.companion.translateCode -> {
                //韩语罗马音
                block.invoke(RomaRepository.korean2roma(text))
            }

            HdLangWrapper.YUE.companion.translateCode -> {
                //粤语拼音
                block.invoke(RomaRepository.cantonese2roma(text))
            }

            HdLangWrapper.JA.companion.translateCode -> {
                //日语罗马音
                block.invoke(RomaRepository.japanese2roma(text))
            }

            HdLangWrapper.ZH.companion.translateCode,
            HdLangWrapper.CHT.companion.translateCode,
            HdLangWrapper.WYW.companion.translateCode
            -> {
                //汉语拼音
                block.invoke(RomaRepository.chinese2pinyin(text))
            }

            else -> {
                block.invoke(null)
            }
        }
    }
}